﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace Apewer.Web
{

    /// <summary>响应。</summary>
    public sealed class MiniResponse
    {

        bool _disposed = false;
        
        /// <summary>上下文。</summary>
        public MiniContext Context { get; private set; }

        /// <summary>保持连接。</summary>
        internal bool KeepAlive { get; set; }

        /// <summary>HTTP 状态码。</summary>
        /// <remarks>默认值：200</remarks>
        public int Status { get; set; }

        /// <summary>头。</summary>
        public StringPairs Headers { get; set; }

        /// <summary>内容类型。</summary>
        public string ContentType { get; set; }

        /// <summary>内容长度。</summary>
        public long ContentLength { get; set; }

        /// <summary>重定向地址。</summary>
        internal string Location { get; set; }

        /// <summary></summary>
        public Stream Body { get => Context.Connection.GetResponseStream(); }

        internal MiniResponse(MiniContext context)
        {
            Context = context;
            Headers = new StringPairs();
            ContentLength = -1;
            Status = 200;
        }

        /// <summary></summary>
        public Json ToJson()
        {
            var json = new Json();
            json.SetProperty("Status", Status);
            json.SetProperty("Location", Location);
            json.SetProperty("ContentType", ContentType);
            json.SetProperty("ContentLength", ContentLength);
            json.SetProperty("Headers", Json.From(Headers));
            return json;
        }

        /// <summary>重定向到指定的 URL。</summary>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentException"></exception>
        public void Redirect(string url, int status)
        {
            if (url == null) throw new ArgumentNullException(nameof(url));
            url = TextUtility.Trim(url);
            if (url.IsEmpty()) throw new ArgumentException("参数 url 为空。");
            Status = 302;
            Location = url;
        }

        void Close(bool force)
        {
            if (_disposed) return;
            _disposed = true;
            Context.Connection.Close(force);
        }

        /// <summary>关闭连接。</summary>
        public void Close() => Close(false);

        #region cookies

        /// <summary>生成 Cookie 的头字段。</summary>
        public static string Format(Cookie cookie)
        {
            if (cookie == null) return null;
            if (string.IsNullOrEmpty(cookie.Name)) return null;

            var segs = new List<string>(4);
            if (cookie.Version > 0) segs.Add("Version=" + cookie.Version.ToString());
            if (!string.IsNullOrEmpty(cookie.Name)) segs.Add(cookie.Name + "=" + (cookie.Value ?? ""));
            if (!string.IsNullOrEmpty(cookie.Path)) segs.Add("Path=" + cookie.Path);
            if (!string.IsNullOrEmpty(cookie.Domain)) segs.Add("Domain=" + cookie.Domain);
            if (!string.IsNullOrEmpty(cookie.Port)) segs.Add("Port=" + cookie.Port);

            if (segs.Count < 1) return null;
            var text = string.Join(";", segs.ToArray());
            return text;
        }

        static string QuotedString(Cookie cookie, string value)
        {
            if (cookie.Version == 0 || IsToken(value)) return value;
            else return "\"" + value.Replace("\"", "\\\"") + "\"";
        }

        static bool IsToken(string value)
        {
            // from RFC 2965, 2068
            const string tspecials = "()<>@,;:\\\"/[]?={} \t";

            int len = value.Length;
            for (int i = 0; i < len; i++)
            {
                char c = value[i];
                if (c < 0x20 || c >= 0x7f || tspecials.IndexOf(c) != -1) return false;
            }
            return true;
        }

        #endregion

    }

}
